home *** CD-ROM | disk | FTP | other *** search
- /*
- File: OSLBldSt.c (Orignal name: OSLBuildStructs.c)
-
- Contains:
-
- Owned by: Nick Pilch
-
- Copyright: © 1993 - 1996 by Apple Computer, Inc., all rights reserved.
-
- Change History (most recent first):
-
- <2> 1/15/96 TJ Cleaned Up
- <4> 1/12/95 jpa Don't use obsolete Toolbox names [1211211]
- <3> 11/15/94 NP 1191221-added warning at call of PtrToHand.
- <2> 8/19/94 NP 1181622: Ownership fix.
- <7> 5/2/94 eeh bug #1160654: various PPC native changes
- <6> 11/2/93 NP Moved back pascal keyword for MPW C.
- <5> 11/2/93 NP Move pascal keyword.
- <4> 10/22/93 NP Removed unnecessary assignment, and thus,
- compiler warning.
- <3> 7/28/93 NP Mods for new token type, OSLToken.
- <2> 7/21/93 NP Fixed #includes.
- <1> 7/21/93 NP first checked in
-
- To Do:
- In Progress:
- */
-
- /*
- ©Apple Computer, Inc. 1992
- All Rights Reserved.
- Author: Eric House
- */
-
-
- #include "OSLPriv.h"
- #include <SetJmp.h>
-
- #pragma segment AEObjSuppt
-
- static OSErr
- ClearNewHandle( Handle *theH, long size )
- {
- *theH = NewHandleClear( size ) ;
- return MemError() ;
- }
-
-
-
- ///////////////////////////////////////////////////////////////////////////////
- // MakeWhoseDescriptor
- // packs the selection data for a 'whose' naming form. This type of naming
- // names the desired object by specifying an identifying test. This is
- // probably a pretty familiar form of utility by this point, but essentially
- // it makes up the record, fills in fields from the parameters, and packs them
- // into a descriptor.
- ///////////////////////////////////////////////////////////////////////////////
-
- static OSErr
- MakeWhoseDescriptor( AEDesc *indexOrRel, AEDesc *test, AEDesc* theDescriptor )
- {
- AERecord whoseRecord ;
- OSErr err = noErr ;
-
- err = AECreateList( NULL, 0, true, &whoseRecord ) ; // create the record
- if ( err != noErr ) goto L100 ;
-
- // the indexOrRel field, which says which object or objects that meet
- // the test are desired, this index can also be a relative record
-
- err = AEPutKeyDesc( &whoseRecord, keyAEIndex, indexOrRel ) ;
- if ( err != noErr ) goto L100 ;
-
- // now we fill in the test we will use
-
- err = AEPutKeyDesc( &whoseRecord, keyAETest, test ) ;
- if ( err != noErr ) goto L100 ;
-
- // dispose of input
-
- IgnoreOSErr( AEDisposeDesc( indexOrRel ) ) ;
- IgnoreOSErr( AEDisposeDesc( test ) ) ;
-
- // coerce record to descriptor
- err = AECoerceDesc( &whoseRecord, typeWhoseDescriptor, theDescriptor ) ;
- if ( err == noErr ) goto L200 ;
-
- L100:
- MakeNull( theDescriptor ) ;
- L200:
- IgnoreOSErr( AEDisposeDesc( &whoseRecord ) ) ;
- return err ;
- } // MakeWhoseDescriptor
-
-
- /*———————————————————————— CreateCompare ————————————————————————*/
-
- OSErr
- CreateCompare( AEDesc input , Comparison *theComparison )
- /*create a comparison record from a descriptor of type typeCompDescriptor*/
- {
- AERecord tempRecord ;
- DescType ignoreReturnedType ; /* <eeh> never checked */
- long actualSize ;
- AEDesc tempObject ;
- OSErr err ;
-
-
- err = ClearNewHandle( (Handle *)theComparison, sizeof( CompareRecord ) ) ;
- if ( err != noErr ) goto L100 ;
-
- /* Using NewHandleClear saves the following calls:
- WITH theComparison** DO
- {
- obj1 = NULL ;
- obj2 = NULL ;
- value = false ;
- redo = false ;
- } ; */
-
- HLock( (Handle)*theComparison ) ;
-
- err = AEDuplicateDesc( &input, &(**theComparison)->theCompInput ) ;
- if ( err != noErr ) goto L200 ;
-
- err = AECoerceDesc( &input, typeAERecord, &tempRecord ) ;
- if ( err != noErr ) goto L300 ;
-
- // WITH theComparison** DO
- {
- ComparePtr cp = **theComparison ;
-
- err = AEGetKeyPtr( &tempRecord, keyAECompOperator,
- typeEnumerated, &ignoreReturnedType,
- (Ptr)&cp->oper, sizeof(cp->oper), &actualSize ) ;
- if ( err != noErr ) goto L350 ;
-
- err = AEGetKeyDesc( &tempRecord, keyAEObject1, typeWildCard, &tempObject ) ;
- if ( err != noErr ) goto L350 ;
-
- err = CreateObject( &tempObject, NULL, true, &cp->obj1 ) ; /* obj1 is NULL until set here */
- if ( err != noErr ) goto L400 ;
-
- IgnoreOSErr( AEDisposeDesc( &tempObject ) ) ;
- err = AEGetKeyDesc( &tempRecord, keyAEObject2, typeWildCard, &tempObject ) ;
- if ( err != noErr ) goto L450 ;
-
- err = CreateObject( &tempObject, NULL, true, &cp->obj2 ) ; /* obj2 is NULL until set here */
- IgnoreOSErr( AEDisposeDesc( &tempObject ) ) ;
-
- /*okay, we've got all of the data, now we set the redo flag so that the first
- time we evaluate the comparison, everything tries to evaluate at least once*/
- cp->redo = true;
- }
-
- IgnoreOSErr( AEDisposeDesc( &tempRecord ) ) ;
- HUnlock( (Handle) *theComparison ) ;
-
- if ( err != noErr )
- {
- DisposeObj( (**theComparison)->obj2 ) ;
- L450:
- DisposeObj( (**theComparison)->obj1 ) ;
- L400:
- IgnoreOSErr( AEDisposeDesc( &tempObject ) ) ;
- L350:
- IgnoreOSErr( AEDisposeDesc( &tempRecord ) ) ;
- L300:
- if ( SetErrDesc( (**theComparison)->theCompInput ) )
- (**theComparison)->theCompInput.dataHandle = NULL ;
- L200:
- DisposeHandle( (Handle)*theComparison ) ;
- theComparison = NULL ; /* 4/11 caller's fail will attempt a second dispose */
- }
- L100:
-
- return err ;
-
- } /*CreateCompare*/
-
-
- /*———————————————————————— CreateLogical ————————————————————————*/
-
- /*create a logical record from a descriptor of type typeLogicalDescriptor*/
- OSErr
- CreateLogical( const AEDesc *input , Logical *theLogical )
-
- {
- AERecord tempRecord ;
- AEDesc tempList ;
- long nTerms ;
- AEKeyword ignoredKeyword ;
- AEDesc dThisTerm ;
- Term thisTerm ;
- Term lastTerm ;
- DescType theReturnedType ;
- long actualSize ;
- long I ;
-
- OSErr err = noErr;
-
- tempRecord.dataHandle = NULL;
- tempList.dataHandle = NULL;
- lastTerm = NULL;
-
- FailErr( ClearNewHandle( (Handle *)theLogical, sizeof(LogicalRecord) ),
- err, errExit ) ;
-
- /* Using NewHandleClear saves the following calls:
- WITH theLogical** DO
- {
- firstTerm = NULL ;
- value = false ;
- redo = false ;
- } ; */
-
- HLock( (Handle) *theLogical ) ;
-
- FailErr( AEDuplicateDesc( input, &(**theLogical)->theLogicalInput ),
- err, errExit ) ;
- FailErr( AECoerceDesc(input, typeAERecord, &tempRecord), err, errExit);
-
- //WITH theLogical** DO
- {
- LogicalPtr lp = **theLogical ;
-
- FailErr( AEGetKeyPtr( &tempRecord, keyAELogicalOperator, typeEnumerated,
- &theReturnedType, (Ptr)&lp->logicalOp, sizeof(lp->logicalOp),
- &actualSize), err, errExit) ;
-
- FailErr( AEGetKeyDesc( &tempRecord, keyAELogicalTerms, typeWildCard,
- &tempList ), err, errExit ) ;
-
- FailErr( AECountItems( &tempList, &nTerms), err, errExit ) ;
-
- for( I = 1; I <=nTerms; ++I ) /* build a linked list of comparisons */
- {
- FailErr( AEGetNthDesc( &tempList, I, typeWildCard, &ignoredKeyword,
- &dThisTerm), err, errExit ) ;
- FailErr( CreateTerm( &dThisTerm, &thisTerm ), err, errExit ) ;
-
- if ( lastTerm == NULL )
- {
- lp->firstTerm = thisTerm;
- lastTerm = thisTerm;
- }
- else
- {
- (*lastTerm)->next = thisTerm;
- lastTerm = thisTerm;
- }
-
- } /*for*/
-
- /*set the redo flag so that everything tries to evaluate at least once*/
- lp->redo = true;
- }
-
- HUnlock( (Handle)*theLogical ) ;
-
- IgnoreOSErr( AEDisposeDesc( &tempRecord) ) ;
- IgnoreOSErr( AEDisposeDesc( &tempList ) ) ;
-
- FAIL_ERR_PROC(err, errExit)
- if ( theLogical != NULL )
- {
- if ( SetErrDesc( (**theLogical)->theLogicalInput ) )
- (**theLogical)->theLogicalInput.dataHandle = NULL ;
- DisposeTerm( (**theLogical)->firstTerm) ;
- };
- DisposeHandle( (Handle)*theLogical ) ;
- *theLogical = NULL;
-
- IgnoreOSErr( AEDisposeDesc( &tempRecord ) ) ;
- IgnoreOSErr( AEDisposeDesc( &tempList ) ) ;
- IgnoreOSErr( AEDisposeDesc( &dThisTerm ) ) ;
- END_FAIL_ERR_PROC(err)
- } /*CreateLogical*/
-
-
- /*———————————————————————— CreateObject ————————————————————————*/
-
- extern pascal Boolean IsKnownAbso( DescType abso ) ;
-
- /* RangeIsWhoseable: eeh 2/1/90
- Determine if ( a range can be converted to data that can be inserted into the structure for
- resolving whose descriptors; if ( it can, convert it to a special type desc and pass it
- back.
- */
- #define cleanupNow false
-
- /* A bit different from the FailErr()s. RangeIsWhoseable returns a Boolean
- * rather than an error, so I can use ExitIfNot to bail whenever, even to
- * clean up when there's been no error */
-
-
- static void
- ExitIfNot( Boolean b, jmp_buf *jbp )
- {
- if ( !b )
- {
- longjmp( *jbp, 1 ) ;
- }
- }
-
- #define sizeZero 0
- static OSErr
- GetWhoseEndPoint( AEDesc dEndObj, long *value , DescType *valCase,
- AEDesc tempRIWRecord, DescType objClass, jmp_buf *jbp )
-
- {
- DescType theReturnedType ;
- DescType scratch ; /* used as temporary storage for all sorts of tests */
- long actualSize ;
- OSErr err = noErr ;
-
- IgnoreOSErr( AEDisposeDesc( &tempRIWRecord ) ) ;
- FailErr( AECoerceDesc( &dEndObj, typeAERecord, &tempRIWRecord ),
- err, errExit ) ;
- FailErr( AEGetKeyPtr( &tempRIWRecord, keyAEContainer, typeWildCard,
- &theReturnedType, NULL, sizeZero, &actualSize ), err, errExit ) ;
- ExitIfNot( theReturnedType == typeCurrentContainer, jbp ) ;
- FailErr( AEGetKeyPtr( &tempRIWRecord, keyAEDesiredClass, typeType,
- &theReturnedType, (Ptr)&scratch, SizeOf(scratch), &actualSize),
- err, errExit ) ;
- ExitIfNot( scratch == objClass, jbp ) ;
- FailErr( AEGetKeyPtr( &tempRIWRecord, keyAEKeyForm, typeEnumerated,
- &theReturnedType, (Ptr)&scratch, sizeof(scratch), &actualSize),
- err, errExit ) ;
- ExitIfNot( scratch == formAbsolutePosition, jbp ) ;
- FailErr( AEGetKeyPtr( &tempRIWRecord, keyAEKeyData, typeWildCard, valCase,
- (Ptr)value, sizeof(*value), &actualSize), err, errExit ) ;
- ExitIfNot( (actualSize == sizeof(value))
- && ((*valCase == typeAbsoluteOrdinal)
- || (*valCase == typeLongInteger)), jbp ) ;
-
- FAIL_ERR_PROC(err, errExit)
- END_FAIL_ERR_PROC(err)
- } /* GetWhoseEndPoint */
-
-
- static Boolean
- RangeIsWhoseable( DescType objClass, AEDesc rangeDesc,
- IndexRecord *index, OSErr *externalErr )
- {
- AEDesc dStartObj, dStopObj ;
- AEDesc tempRIWRecord ;
- OSErr err ;
- Boolean retVal = false ;
- jmp_buf jb ;
-
- dStartObj.dataHandle = NULL ;
- dStopObj.dataHandle = NULL ;
- tempRIWRecord.dataHandle = NULL ;
-
- *externalErr = noErr ;
-
- if (setjmp( jb) ) // we'll come back here if it is determined that
- { // the answer is false
- // IgnoreOSErr( AEDisposeDesc( &tempRIWRecord ) ) ;
- // IgnoreOSErr( AEDisposeDesc( &dStartObj ) ) ;
- // IgnoreOSErr( AEDisposeDesc( &dStopObj ) ) ;
- retVal = false ;
- err = noErr ;
- goto errExit ; // not really an error, but...
- }
-
- FailErr( AECoerceDesc( &rangeDesc, typeAERecord, &tempRIWRecord ),
- err, errExit ) ;
-
- FailErr( AEGetKeyDesc( &tempRIWRecord, keyAERangeStart, typeWildCard,
- &dStartObj ), err, errExit ) ;
- FailErr( AEGetKeyDesc( &tempRIWRecord, keyAERangeStop, typeWildCard,
- &dStopObj ), err, errExit ) ;
-
- FailErr( GetWhoseEndPoint( dStartObj, &index->startValue, &index->startCase,
- tempRIWRecord, objClass, (jmp_buf *)&jb ), err, errExit ) ;
- FailErr( GetWhoseEndPoint( dStopObj, &index->stopValue, &index->stopCase,
- tempRIWRecord, objClass, (jmp_buf *)&jb ), err, errExit ) ;
-
- retVal = true ; /* if we've gotten this far, it's true */
- // ExitIfNot( cleanupNow ) ;
-
-
- errExit :
- IgnoreOSErr( AEDisposeDesc( &dStartObj) ) ;
- IgnoreOSErr( AEDisposeDesc( &dStopObj) ) ;
- IgnoreOSErr( AEDisposeDesc( &tempRIWRecord) ) ;
- *externalErr = err ;
- return retVal ;
-
- } /* RangeIsWhoseable */
-
-
- /* CombineObjects:
- * this could be done without parameters, but I find this style much easier
- * to read and to maintain.
- * Combines two objects into one. On entry, objWithTest has selectionData
- * that needs to be moved to objWithIndex, whose selectionData should
- * already have been disposed of.
- */
- static void
- CombineObjects( Object *objWithTest, Object *objWithIndex )
- {
- Object tempContainerH ; /* used for swapping */
-
- //WITH objWithTest** DO
- {
- ObjRecordPtr orp = **objWithTest ;
-
- IgnoreOSErr( AEDisposeDesc( &orp->theObjInput ) ) ;
- (**objWithIndex)->u.objForm = formWhose ;
- (**objWithIndex)->objContainer = orp->objContainer ;
- (**objWithIndex)->objSelectionData = orp->objSelectionData ;
- if ( orp->objContainer != NULL )
- (*(orp->objContainer))->objContained = *objWithIndex ;
- tempContainerH = orp->objContainer ;
- orp->objContainer = NULL ; /* so DisposeObj doesn't follow the chain */
- orp->objSelectionData.dataHandle = NULL ; /* " */
- DisposeObj( *objWithTest ) ;
- }
-
- *objWithTest = tempContainerH ; /* so the current makeobj call returns right values */
- } /* CombineObjects */
-
-
- /*create a term record from either a typeLogicalDescriptor or a typeCompDescriptor.
- Do not dispose input: app may own it.*/
- OSErr
- CreateObject( const AEDesc *input , Object containedObj,
- Boolean expandWhoseData, Object *theObject )
-
- {
- AEDesc tempObject ;
- AEDesc tempRecord ;
- DescType theReturnedType ;
- Size actualSize;
- Object newObj ;
- Boolean canCombine ;
- //Boolean disposedSelf ; /* if dispose self for optimization, don't unlock Handle! */
- IndexRecord index ;
-
-
- OSErr err = noErr;
-
- tempObject.dataHandle = NULL;
- tempRecord.dataHandle = NULL;
-
- FailErr( ClearNewHandle( (Handle *)&newObj, sizeof(ObjRecord) ), err, errExit ) ;
-
- /* Using NewHandleClear saves the following calls:
- WITH newObj** DO
- {
- objContainer = NULL ;
- objContained = NULL ;
- objSelectionData.dataHandle = NULL ;
- objTheWhose = NULL ;
- objValue.dataHandle = NULL ;
- valIsExmn = false ;
- objRedo = false ;
- } ; */
-
- /* <eeh> 4/8 does it really make sense to put a copy of the desc in the record in any case
- but that where it is an object. Who cares what the input is when it's a text descriptor.
- And will we look pretty silly returning ['text', "spinnaker"] when a memory error occurs? */
-
- (*newObj)->objContained = containedObj ;
- (*newObj)->objValue.descriptorType = typeNull ;
-
- /*set the redo flag so that everything tries to evaluate at least once*/
- (*newObj)->objRedo = true;
-
- HLock( (Handle)newObj ) ;
-
- FailErr( AEDuplicateDesc( input, &(*newObj)->theObjInput ), err, errExit ) ;
-
- switch( input->descriptorType )
- {
- case typeNull:
- (*newObj)->objClass = typeNull ;
- break ;
-
-
- case typeToken : /* 4/4; dataHandle is to a token descriptor */
- // WITH newObj** DO
- (*newObj)->objValue =
- (*(ContainedTokenRecHandle)(input->dataHandle))->token ;
- (*newObj)->u.tokenClass =
- (*(ContainedTokenRecHandle)(input->dataHandle))->tokenClass ;
- (*newObj)->objClass = typeToken ;
- (*newObj)->objRedo = false;
- break ;
-
- case typeObjectBeingExamined :
- (*newObj)->objClass = typeObjectBeingExamined ;
- break ;
-
- case typeObjectSpecifier :
- FailErr( AECoerceDesc( input, typeAERecord, &tempRecord ), err, errExit ) ;
-
- //WITH newObj** DO
- /*get the selector form*/
- {
- ObjRecordPtr op = *newObj ;
-
- FailErr( AEGetKeyPtr( &tempRecord, keyAEKeyForm, typeEnumerated,
- &theReturnedType, (Ptr)&op->u.objForm, sizeof(op->u.objForm),
- &actualSize), err, errExit ) ;
-
- /*get the desired type*/
-
- FailErr( AEGetKeyPtr( &tempRecord, keyAEDesiredClass, typeType,
- &theReturnedType, (Ptr)&op->objClass, SizeOf(op->objClass), &actualSize),
- err, errExit ) ;
-
- /*get the selector data; put it in the object record so recursive call can get it.*/
- FailErr( AEGetKeyDesc( &tempRecord, keyAEKeyData, typeWildCard,
- &op->objSelectionData ), err, errExit ) ;
-
- /*
- HERE IS WHERE WE RECURSIVELY CALL OURSELVES.
- Optimization may occur here. Get the container object.
- */
-
- FailErr( AEGetKeyDesc( &tempRecord, keyAEContainer, typeWildCard,
- &tempObject ), err, errExit ) ;
- FailErr( CreateObject( &tempObject, newObj, expandWhoseData,
- &op->objContainer ), err, errExit ) ;
- IgnoreOSErr( AEDisposeDesc( &tempObject ) ) ;
-
- /* Now look at the selector data (which may have been altered by the recursive CreateObject
- call) and if ( it is a whose ) create the test record. if ( we don't want to dispose of
- the selectionData, set tempObject's Handle to NULL. */
-
- if ( (op->u.objForm == formWhose) && expandWhoseData )
- {
- FailErr( CreateWhose( op->objSelectionData,
- (Whose*)&op->objTheWhose ), err, errExit ) ;
- IgnoreOSErr( AEDisposeDesc( &op->objSelectionData ) ) ;
- }
-
- /* else do nothing: the selectionData already holds tempObject */
-
- /* Now look for simplifications that can/must be done. If the class of object and its
- container are the same there is the possibility of combining the two operations into
- one. if ( the form is formTest we MUST optimize; if ( the form of the contained is
- formAbsolutePosition we can combine the two; if ( it is anything else (for now) we convert the
- test to a phony whose-clause with kAEAll as its index field. */
-
- /* can we combine them?
- NOTE: this is outside the if below because I want to make adding other
- optimizations as easy as possible. if we decide this is to be all there
- is it should be moved inside. */
- canCombine = (containedObj != NULL)
- && (op->objClass == (*containedObj)->objClass) ;
-
- /* Now see if there are any optimizations we can make. Optimizations, in this case,
- mean folding two object records together and combining their selection data into
- a single descriptor. We attempt to combine the object record associated with
- the current invocation of CreateObj() with that belonging to the invocation that
- called us by folding the necessary stuff into the other and disposing of this one.*/
-
-
- if ( op->u.objForm == formTest )
- {
- if ( canCombine && ((*containedObj)->u.objForm == formAbsolutePosition)
- && (((*containedObj)->objSelectionData.descriptorType == typeLongInteger)
- || (((*containedObj)->objSelectionData.descriptorType
- == typeAbsoluteOrdinal)
- && IsKnownAbso( **(LongHandle)
- (*containedObj)->objSelectionData.dataHandle ) )) )
- {
- index.startValue = **((LongHandle)
- ((*containedObj)->objSelectionData.dataHandle)) ;
- index.startCase = (*containedObj)->objSelectionData.descriptorType ; /* was typelongeger */
- index.stopCase = typeNull ;
-
- /* now dispose of the containing obj and fix the pointers */
- IgnoreOSErr( AEDisposeDesc( &(*containedObj)->objSelectionData ) ) ;
- }
- else if ( canCombine && ((*containedObj)->u.objForm == formRange)
- && RangeIsWhoseable( op->objClass,
- (*containedObj)->objSelectionData, &index, &err )
- && err == noErr )
- {
- IgnoreOSErr( AEDisposeDesc( &(*containedObj)->objSelectionData ) ) ; /* no longer need range */
- }
- else if ( err != noErr ) // <eeh> added with port b/c of loss
- { // of nested procedures
- goto errExit ;
- }
- else
- {
- op->u.objForm = formWhose ;
- index.startCase = typeAbsoluteOrdinal ;
- index.startValue = (long)kAEAll ;
- index.stopCase = typeNull ;
- canCombine = false ; /* 4/4 fixes bug where optimization takes place though shouldn't */
- }
- FailErr( AECreateDesc( typeWhoseRangeInternal, (Ptr)&index,
- sizeof(index), &tempObject ), err, errExit ) ;
- FailErr( MakeWhoseDescriptor( &tempObject, &op->objSelectionData,
- &op->objSelectionData ), err, errExit ) ; /* disposes its inputs */
- if ( canCombine ) /* really: if ( shouldCombine ... */
- CombineObjects( &newObj, &containedObj ) ; /* fold both into 2nd */
- }
- } // "WITH"
-
- IgnoreOSErr( AEDisposeDesc( &tempRecord ) ) ;
- break ;
-
- default :
- /* This is just a token or descriptor. We will not need to resolve
- it further */
- //WITH newObj** DO
-
- /* The question what value to assign class in the case where an obj's type
- * is
- * really not distinct from its class is related to that of how to tell whether
- * the value of an obj is a token or a descriptor we own. Or at least the
- * solutions are likely to be related.
-
- * if ( we get here with a token, ) we must pay careful attention to the class
- * as well as the type of the token. Yet if ( we get here with, say, as desc
- * of type text and data "string" we were probably called by CreateCompare or
- * somesuch which has little use for the concept of class. For now, it's
- * probably best to have those routines pass type as class. But this whose
- * question is really one that could bear some revisitation. */
-
- (*newObj)->objClass = input->descriptorType ;
-
- /* <eeh> I assume there is no way this could _ever_ be a token */
- {
- // I WANT TO EXACTLY DUPLICATE THE FUNCTIONALITY OF THE COMMENTED OUT STATEMENT
- // BELOW.
- AEDesc tempDesc;
- OSErr error;
-
- error = AEDuplicateDesc(input, &tempDesc);
- ((*newObj)->objValue).descriptorType = tempDesc.descriptorType;
- ((*newObj)->objValue).dataHandle = tempDesc.dataHandle;
- if (error)
- FailErr(error, err, errExit);
- }
- // FailErr( AEDuplicateDesc( input, &(*newObj)->objValue ), err, errExit ) ;
- /* caller knows whether to dispose input */
-
- (*newObj)->objRedo = false;
-
- } // switch
-
- /* IgnoreOSErr( AEDisposeDesc( tempObject )) ; */
- /* pAssert( tempObject.dataHandle = NULL, 'was not NULL' ) ; */
-
- HUnlock( (Handle)newObj ) ;
- *theObject = newObj;
- return err ;
-
-
- FAIL_ERR_PROC(err, errExit)
- if ( newObj != NULL )
- {
- HLock( (Handle)newObj ) ;
- // WITH newObj** DO
- {
- ObjRecordPtr op = *newObj ;
- if ( ! SetErrDesc( op->theObjInput ) )
- IgnoreOSErr( AEDisposeDesc( &(*newObj)->theObjInput ) ) ;
- IgnoreOSErr( AEDisposeDesc( &op->objSelectionData ) ) ;
- DisposeWhose( (Whose)op->objTheWhose ) ; /* <eeh> Do I need this? */
- DisposeObj( op->objContainer ) ;
- }
- DisposeHandle( (Handle) newObj ) ;
- }
- IgnoreOSErr( AEDisposeDesc( &tempObject ) ) ;
- IgnoreOSErr( AEDisposeDesc( &tempRecord ) ) ;
- *theObject = NULL;
- END_FAIL_ERR_PROC(err)
-
- } /*CreateObject*/
-
-
-
- void
- zero( char *s, long bytes )
- {
- while ( bytes-- )
- *s++ = 0 ;
- }
-
- static OSErr
- CreateCompareEvt( AEDesc *input, CompareEvent *output)
- {
- CompareEvtRecord cer ;
- OSErr err = noErr ;
- CompareEvent newCompEvnt = NULL ;
- DescType theRtndType ;
- DescType cEventClass ;
- DescType cEventID ;
- long actualSize ;
- ProcessSerialNumber psn = { 0, kCurrentProcess } ;
- AEAddressDesc target ;
- AEDesc params, tempDesc ;
- AEKeyword theAEKeyword ;
- long numElements ;
-
- zero( (char *)&cer, sizeof(cer) ) ;
- params.dataHandle = NULL ;
- target.dataHandle = NULL ;
- tempDesc.dataHandle = NULL ;
-
- FailErr( AECreateDesc( typeProcessSerialNumber, (Ptr)&psn, sizeof(psn),
- &target ), err, errExit ) ;
-
- FailErr( AEGetKeyPtr( input, keyEventClassParam, typeType,
- &theRtndType, (Ptr)&cEventClass, sizeof(cEventClass), &actualSize ),
- err, errExit ) ;
-
- FailErr( AEGetKeyPtr( input, keyEventIDParam, typeType,
- &theRtndType, (Ptr)&cEventID, sizeof(cEventID), &actualSize),
- err, errExit ) ;
-
- FailErr( AECreateAppleEvent( cEventClass, cEventID, &target,
- kAutoGenerateReturnID, kAnyTransactionID, &cer.eventWParams ),
- err, errExit ) ;
-
- IgnoreOSErr( AEDisposeDesc( &target ) ) ;
-
- // now move the params from the incomming descriptor to the AppleEvent
- // we'll be sending as the event.
-
- FailErr( AEGetKeyDesc( input, keyCompEvtParams, typeAERecord,
- ¶ms ), err, errExit ) ;
-
- FailErr( AECountItems( ¶ms, &numElements ), err, errExit ) ;
- while ( numElements )
- {
- FailErr( AEGetNthDesc( ¶ms, numElements, typeWildCard,
- &theAEKeyword, &tempDesc ), err, errExit ) ;
- FailErr( AEPutParamDesc( &cer.eventWParams, theAEKeyword, &tempDesc ),
- err, errExit ) ;
- IgnoreOSErr( AEDisposeDesc( &tempDesc ) ) ;
- --numElements ;
- }
- IgnoreOSErr( AEDisposeDesc( ¶ms ) ) ;
-
-
- cer.value = false ;
- cer.redo = true ;
-
- // FailErr( AEDuplicateDesc( input, &cer.theCompEvtInput ), err, errExit ) ;
- cer.theCompEvtInput = *input ;
- input->dataHandle = NULL ; // so the later dispose won't do any harm
-
- DebugStr("\pWarning: PtrToHand being called. Result will be wrong.");
- PtrToHand( &cer, (Handle *)&newCompEvnt, sizeof(cer) ) ;
- FailErr( MemError(), err, errExit ) ;
-
- *output = newCompEvnt ;
-
- FAIL_ERR_PROC(err, errExit)
- if ( cer.eventWParams.dataHandle )
- IgnoreOSErr( AEDisposeDesc( &cer.theCompEvtInput ) ) ;
- if ( target.dataHandle )
- IgnoreOSErr( AEDisposeDesc( &target ) ) ;
- if ( tempDesc.dataHandle )
- IgnoreOSErr( AEDisposeDesc( &tempDesc ) ) ;
- END_FAIL_ERR_PROC(err)
-
- } // CreateCompareEvt
-
-
-
- /*———————————————————————— CreateTerm ————————————————————————*/
-
- /*create a term record from either a typeLogicalDescriptor or
- * a typeCompDescriptor*/
- OSErr
- CreateTerm( AEDesc *input, Term *theTerm )
- {
- OSErr err = noErr;
-
- FailErr( ClearNewHandle( (Handle *)theTerm, sizeof(TestTermRecord) ),
- err, errExit ) ;
-
- /* Using NewHandleClear saves the following calls:
- WITH theTerm^^ DO
- {
- next := NULL ;
- value := false ;
- redo := false ;
- ttype := kCompare ;
- comp/log := NULL ;
- } ; */
-
- HLock( (Handle) *theTerm ) ;
- FailErr( AEDuplicateDesc( input, &(**theTerm)->theTermInput ), err, errExit ) ;
-
- // WITH theTerm^^ DO
- {
- register TestTermPtr tp = **theTerm ;
- switch ( input->descriptorType )
- {
- case typeLogicalDescriptor :
- tp->ttype = kLogical;
- FailErr( CreateLogical( input, &tp->u.log ), err, errExit ) ;
- break ;
- case typeCompDescriptor :
- tp->ttype = kCompare ;
- FailErr( CreateCompare( *input, &tp->u.compar ), err, errExit ) ;
- break ;
- case typeCompEvtDescriptor :
- tp->ttype = kCompareEvt ;
- FailErr( CreateCompareEvt( input, &tp->u.cEvt ),
- err, errExit ) ;
- break ;
- default :
- err = errAEBadTestKey ;
- goto errExit ;
- }
-
-
- /* set the redo flag so that everything tries to evaluate at least once */
- tp->redo = true;
- }
-
- HUnlock( (Handle) *theTerm ) ;
- IgnoreOSErr( AEDisposeDesc( input ) ) ;
-
- FAIL_ERR_PROC(err, errExit)
- if ( *theTerm != NULL )
- {
- if ( SetErrDesc( (**theTerm)->theTermInput ) )
- (**theTerm)->theTermInput.dataHandle = NULL ;
- if ( (**theTerm)->ttype == kLogical )
- DisposeLogical( (Logical)(**theTerm)->u.log ) ;
- else
- DisposeCompare((Comparison)(**theTerm)->u.compar ) ;
- DisposeTerm( (**theTerm)->next ) ;
- }
- DisposeHandle( (Handle)*theTerm ) ;
- *theTerm = NULL ;
- END_FAIL_ERR_PROC(err)
-
- } /* CreateTerm */
-
-
- /*———————————————————————— CreateWhose ————————————————————————*/
-
- static OSErr
- AdjustIndexValue( long *result, DescType *specialCase )
- {
- if ( *specialCase == typeAbsoluteOrdinal )
- {
- *specialCase = (DescType)*result ;
- *result = 1 ;
-
- if ( *specialCase == kAEFirst )
- *specialCase = typeLongInteger ;
- else if ( *specialCase == kAELast )
- {
- *specialCase = typeLongInteger ;
- *result = -1 ;
- }
-
- /* Certain special relative forms are not allowed in whose ranges */
- /* <eeh> removed test for kAENext etc. No longer considered in same class
- as Last, Any etc. */
- }
- else if ( (*specialCase != typeLongInteger) && (*specialCase != typeNull) )
- return errAEImpossibleRange ;
-
- return noErr ;
- } // AdjustIndexValue
-
-
-
-
- OSErr
- CreateWhose( AEDesc input , /* do not dispose: may be a whose descriptor an accessor expects to use later */
- Whose *theWhose )
- /*create a Whose record by unpacking the whose descriptor in a range*/
- {
- AEDesc tempObject ;
- AEDesc tempRecord ;
- // DescType theReturnedType ; not used in Pascal original
- // Size actualSize ; same here
- OSErr err = noErr ;
-
- tempObject.dataHandle = NULL;
- tempRecord.dataHandle = NULL;
-
- FailErr( ClearNewHandle( (Handle *)theWhose, sizeof(WhoseRecord) ),
- err, errExit ) ;
-
- /* Using NewHandleClear saves the following calls:
- WITH theWhose^^ DO
- {
- index.start := 0 ;
- index.stop := 0 ;
- theTerm := NULL ;
- value.dataHandle := NULL ;
- } ;
- */
-
- HLock( (Handle) *theWhose ) ;
- FailErr( AEDuplicateDesc( &input, &(**theWhose)->theWhoseInput ),
- err, errExit ) ;
-
- FailErr( AECoerceDesc( &input, typeAERecord, &tempRecord ),
- err, errExit ) ;
-
- // WITH theWhose^^ DO
- {
- WhoseRecordPtr wpr = **theWhose ;
-
- /*get the selector data, and if ( it is a whose ) create the Whose record*/
- FailErr( AEGetKeyDesc( &tempRecord, keyAETest, typeWildCard,
- &tempObject ), err, errExit ) ;
- FailErr( CreateTerm( &tempObject, &wpr->theTerm ),
- err, errExit) ;
-
- FailErr( AEGetKeyDesc( &tempRecord, keyAEIndex, typeWildCard,
- &tempObject ), err, errExit ) ;
-
- if ( tempObject.descriptorType == typeWhoseRangeInternal )
- {
- BlockMove( *(tempObject.dataHandle), (Ptr)&wpr->index,
- sizeof(wpr->index) ) ;
- FailErr( AdjustIndexValue( &wpr->index.startValue,
- &wpr->index.startCase ), err, errExit ) ;
- FailErr( AdjustIndexValue( &wpr->index.stopValue,
- &wpr->index.stopCase ), err, errExit )
- }
- else
- {
- wpr->index.startValue = **((LongHandle)tempObject.dataHandle) ;
- wpr->index.startCase = tempObject.descriptorType ;
- FailErr( AdjustIndexValue( &wpr->index.startValue,
- &wpr->index.startCase ), err, errExit ) ;
- wpr->index.stopCase = typeNull ;
- }
-
- IgnoreOSErr( AEDisposeDesc( &tempObject ) ) ;
- IgnoreOSErr( AEDisposeDesc( &tempRecord ) ) ;
- }
-
- HUnlock( (Handle) *theWhose ) ;
-
- FAIL_ERR_PROC(err, errExit)
- if ( *theWhose != NULL )
- {
- if ( SetErrDesc( (**theWhose)->theWhoseInput ) )
- (**theWhose)->theWhoseInput.dataHandle = NULL ;
- DisposeTerm( (**theWhose)->theTerm ) ;
- }
- IgnoreOSErr( AEDisposeDesc( &tempObject ) ) ;
- IgnoreOSErr( AEDisposeDesc( &tempRecord ) ) ;
- DisposeHandle( (Handle)*theWhose ) ;
- *theWhose = NULL;
- END_FAIL_ERR_PROC(err)
-
- } /*CreateWhose*/
-
-